/*
 * Copyright 2010 - 2011, The PLDesktop Development Team
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 */
#ifndef PLHASHTABLEKEYENUMERATOR_H
#define PLHASHTABLEKEYENUMERATOR_H

#include <tools/PLIEnumerator.h>

namespace PLSDK {

    /**
     * Key enumerator for the hashtable.
     */
    template < typename hashkey, typename hashvalue >
    class PLHashTableKeyEnumerator {
    public:
        /**
         * Constructor.
         *
         * @param enumerator Enumerator interface of the hashtable.
         */
        PLHashTableKeyEnumerator(PLIEnumerator < hashkey, hashvalue > *enumerator);
        /**
         * Copy Constructor.
         *
         * @param enumerator Enumerator to copy.
         */
        PLHashTableKeyEnumerator(const PLHashTableKeyEnumerator &enumerator);
        /**
         * Have the object a next object.
         *
         * @return True if there was a next object.
         */
        inline plbool hasNext();
        /**
         * Have the object a previous object.
         *
         * @return True if there was a previous object.
         */
        inline plbool hasPrevious();
        /**
         * Get the next object.
         *
         * @return The next object.
         */
        inline hashkey next();
        /**
         * Get the previous object.
         *
         * @return The previous object.
         */
        inline hashkey previous();
        /**
         * Reset the enumerator to the first element of the hashtable.
         */
        inline void reset();
        /**
         * Copy operator.
         */
        PLHashTableKeyEnumerator& operator=( const PLHashTableKeyEnumerator &enumerator );
    private:
        PLIEnumerator < hashkey, hashvalue > *m_enumerator;
        pluint m_pos;
    };

    template < typename hashkey, typename hashvalue >
    PLHashTableKeyEnumerator<hashkey, hashvalue>::PLHashTableKeyEnumerator(PLIEnumerator < hashkey, hashvalue > *enumerator) :
        m_enumerator(enumerator), m_pos(0) {}

    template < typename hashkey, typename hashvalue >
    PLHashTableKeyEnumerator<hashkey, hashvalue>::PLHashTableKeyEnumerator(const PLHashTableKeyEnumerator &enumerator) :
        m_enumerator(enumerator.m_enumerator), m_pos(enumerator.m_pos) {}

    template < typename hashkey, typename hashvalue >
    plbool PLHashTableKeyEnumerator<hashkey, hashvalue>::hasNext() {
        return m_enumerator->hasNext(m_pos);
    }

    template < typename hashkey, typename hashvalue >
    plbool PLHashTableKeyEnumerator<hashkey, hashvalue>::hasPrevious() {
        return m_enumerator->hasPrevious(m_pos);
    }

    template < typename hashkey, typename hashvalue >
    hashkey PLHashTableKeyEnumerator<hashkey, hashvalue>::next() {
        return m_enumerator->nextKey(m_pos);
    }

    template < typename hashkey, typename hashvalue >
    hashkey PLHashTableKeyEnumerator<hashkey, hashvalue>::previous() {
        return m_enumerator->previousKey(m_pos);
    }

    template < typename hashkey, typename hashvalue >
    void PLHashTableKeyEnumerator<hashkey, hashvalue>::reset() {
        m_pos = 0;
    }

    template < typename hashkey, typename hashvalue >
    PLHashTableKeyEnumerator<hashkey, hashvalue> &PLHashTableKeyEnumerator<hashkey, hashvalue>::operator=( const PLHashTableKeyEnumerator &enumerator ) {
        m_enumerator = enumerator.m_enumerator;
        m_pos = enumerator.m_pos;
        return *this;
    }

}

#endif
